package yxy.game.pm2.active.module;

import com.alibaba.fastjson.JSONObject;
import org.joda.time.DateTime;
import yxy.apple.util.RandomUtility;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.bean.actturntable;
import yxy.cherry.data.bean.actturntabledate;
import yxy.cherry.data.bean.actturntablereward;
import yxy.game.pm2.active.module.actdata.ActDataCenter;
import yxy.game.pm2.active.module.subordinateclass.Act_夺宝大奖纪录;
import yxy.game.pm2.active.module.subordinateclass.Turntable;
import yxy.game.pm2.active.module.subordinateclass.TurntableRandom;
import yxy.game.pm2.active.module.subordinateclass.TurntableRandomdataInfo;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.db.dao.MySQLCacheDAO;
import yxy.game.pm2.bean.module.PlayerModule;
import yxy.game.pm2.message.ActiveMessage;
import yxy.game.pm2.message.PackageMessage;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.tip.TipHandle;
import yxy.game.pm2.module.tip.TipType;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

//TODO : changzhu
public class ActiveModule_夺宝 extends PlayerModule {

    //bean ---------------------------------------------

    private static final int acttype = 112;

    public static final int 普通夺宝 = 1;
    public static final int 高级夺宝 = 2;

    public Turntable turntable1;    //幸运寻宝
    public Turntable turntable2;    //富贵寻宝

    public Turntable getTurntable1() {
        return turntable1;
    }

    public void setTurntable1(Turntable turntable1) {
        this.turntable1 = turntable1;
    }

    public Turntable getTurntable2() {
        return turntable2;
    }

    public void setTurntable2(Turntable turntable2) {
        this.turntable2 = turntable2;
    }

    public Turntable gainturntable(int type) {
        if (type == 普通夺宝) {
            return getTurntable1();
        }

        if (type == 高级夺宝) {
            return getTurntable2();
        }

        return null;
    }

    //func ----------------------------------------------

    public static ActiveModule_夺宝 create(String pcode) {

        ActiveModule_夺宝 am = new ActiveModule_夺宝();

        Turntable tt1 = am.createturntable(普通夺宝, pcode);
        Turntable tt2 = am.createturntable(高级夺宝, pcode);

        am.setPlayerCode(pcode);
        am.setTurntable1(tt1);
        am.setTurntable2(tt2);
        am.set(true);

        return am;
    }

    /**
     * 创建夺宝信息
     *
     * @param type
     * @return
     */
    public Turntable createturntable(int type, String playercode) {
        Turntable tt = new Turntable();
        tt.setType(type);
        tt.setFreerefresh(true);
        tt.setFrupdatetime(DateTime.now());

        Map<String, actturntable> actturntablemap = ActDataCenter.getAllData(actturntable.class, playercode);
        for (yxy.cherry.data.bean.actturntable actturntable : actturntablemap.values()) {
            if (actturntable.getType() != type) {
                continue;
            }

            TurntableRandomdataInfo randomInfo = new TurntableRandomdataInfo();
            randomInfo.setSequence(actturntable.getPosition());
            randomInfo.setRefresh(actturntable.getRefresh());
            randomInfo.setWeight(actturntable.getWeight());
            randomInfo.setHadget(false);
            randomInfo.setCur(randomcur(actturntable));
            tt.getRandomInfos().add(randomInfo);
        }
        return tt;
    }

    public void refreshturntable(int type) {
        Turntable tt = gainturntable(type);

        Map<String, actturntable> acttaylisurntablemap = ActDataCenter.getAllData(actturntable.class, getPlayerCode());
        tt.setRandomInfos(new ArrayList<TurntableRandomdataInfo>());
        for (yxy.cherry.data.bean.actturntable actturntable : acttaylisurntablemap.values()) {
            if (actturntable.getType() != type) {
                continue;
            }

            TurntableRandomdataInfo randomInfo = new TurntableRandomdataInfo();
            randomInfo.setSequence(actturntable.getPosition());
            randomInfo.setRefresh(actturntable.getRefresh());
            randomInfo.setWeight(actturntable.getWeight());
            randomInfo.setHadget(false);
            randomInfo.setCur(randomcur(actturntable));
            tt.getRandomInfos().add(randomInfo);
        }

        set(false);
    }

    public void refresh() {
        refreshturntable(普通夺宝);
        refreshturntable(高级夺宝);
    }

    /**
     * 随机每个位置的道具
     *
     * @param att
     * @return
     */
    public Currency randomcur(actturntable att) {
        List<TurntableRandom> trs = new ArrayList<TurntableRandom>();
        int[] types = att.getRewardtype();
        int[] ids = att.getRewardid();
        int[] nums = att.getRewardnum();
        int[] percents = att.getPercent();
        for (int i = 0; i < types.length; i++) {
            TurntableRandom tr = new TurntableRandom();
            tr.setRewardtype(types[i]);
            tr.setRewardid(ids[i]);
            tr.setRewardnum(nums[i]);
            tr.setPercent(percents[i]);
            trs.add(tr);
        }
        TurntableRandom tr2 = RandomUtility.randomWeight(trs);
        return tr2.getCur();
    }

    /**
     * 随机奖励
     *
     * @param type
     * @param num
     * @param areaid
     * @param name
     * @return
     */
    public JSONObject randomcur(int type, int num, int areaid, String name) {

        ArrayList<Integer> rollpoints = new ArrayList<Integer>();
        ArrayList<Currency> curs = new ArrayList<Currency>();

        ArrayList<TurntableRandomdataInfo> turntables = new ArrayList<TurntableRandomdataInfo>();
        ArrayList<TurntableRandomdataInfo> trs = new ArrayList<TurntableRandomdataInfo>(); //下一轮随机对象

        turntables = gainturntable(type).getRandomInfos();

        for (TurntableRandomdataInfo info : turntables) {
            if (!info.isHadget()) {
                trs.add(info);
            }
        }

        int handlenum = 0;
        boolean run = true;
        while (handlenum < num && run) {
            TurntableRandomdataInfo tr = RandomUtility.randomWeight(trs);
            curs.add(tr.getCur());

            if (tr.getSequence() == 1) {
                Act_夺宝大奖纪录 msg = Act_夺宝大奖纪录.create(areaid, type, name, tr.getCur());
                msg.add();
            }

            rollpoints.add(tr.getSequence());
            if (tr.getRefresh() == 0) {
                for (TurntableRandomdataInfo info : turntables) {
                    if (info.getSequence() == tr.getSequence()) {
                        info.setHadget(true);
                        trs.remove(tr);
                    }
                }
            }
            handlenum++;
            if (trs.size() == 0) {
                run = false;
            }
        }

        set(false);

        JSONObject json = new JSONObject();
        json.put("curs", curs);
        json.put("rolls", rollpoints);

        return json;
    }

    public ActiveMessage.TurnTableInfo.Builder deal(int areaid, int type) {

        Turntable tt = new Turntable();
        tt = gainturntable(type);

        actturntabledate data = null;
        Map<String, actturntabledate> atdmap = ActDataCenter.getAllData(actturntabledate.class, getPlayerCode());
        for (actturntabledate xls : atdmap.values()) {
            if (xls.getType() == type) {
                data = xls;
            }
        }

        ActiveMessage.TurnTableInfo.Builder build = ActiveMessage.TurnTableInfo.newBuilder();
        build.setType(type);
        build.setFreerefresh(tt.isFreerefresh());

        if (tt.isFreerefresh()) {
            build.setLastfreerefresh(0);
        } else {
            DateTime nowdt = DateTime.now();
            long ntime = nowdt.getMillis();
            long refreshfree = data.getRefreshfree() * 1000;
            long utime = tt.getFrupdatetime().getMillis();
            long time = refreshfree - (ntime - utime);
            build.setLastfreerefresh(time);
        }

        for (TurntableRandomdataInfo ri : tt.getRandomInfos()) {
            ActiveMessage.RandomInfo.Builder ribuild = ActiveMessage.RandomInfo.newBuilder();
            ribuild.setSequence(ri.getSequence());

            Currency cur = ri.getCur();
            PackageMessage.Item.Builder item = PackageMessage.Item.newBuilder();
            item.setType(cur.getType().getNumber());
            item.setDataId(cur.getDataId());
            item.setNumber(cur.getNumber());
            ribuild.setCur(item);

            if (ri.getRefresh() == 0 && ri.isHadget()) {
                ribuild.setHadget(true);
            } else {
                ribuild.setHadget(false);
            }

            build.addRandominfo(ribuild.build());
        }

        if (type == 普通夺宝) {
            long num = Currency.number(getPlayerCode(), CurrencyType.CT_普通夺宝积分, -1, false);
            build.setLuckyvalue(num);
        }

        if (type == 高级夺宝) {
            long num = Currency.number(getPlayerCode(), CurrencyType.CT_高级夺宝积分, -1, false);
            build.setLuckyvalue(num);
        }

        build.addAllGetboxid(tt.getLuckyboxs());

        try {
            // TODO:中奖信息 10条 有序 名字+道具id
            List<Act_夺宝大奖纪录> msgs = Act_夺宝大奖纪录.all(areaid, type);

            for (Act_夺宝大奖纪录 msg : msgs) {
                ActiveMessage.AwardsInfo.Builder ai = ActiveMessage.AwardsInfo.newBuilder();
                ai.setSequence(msg.getTime());
                ai.setItem(new CurrencyHandle().packItem(msg.getCur()));
                ai.setName(msg.getName());
                build.addAwardsinfo(ai.build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return build;
    }

    private void update(Boolean isNewPlayer) {
        actturntabledate at1 = new actturntabledate();
        actturntabledate at2 = new actturntabledate();
        Map<String, actturntabledate> atdmap = ActDataCenter.getAllData(actturntabledate.class, getPlayerCode());
        for (actturntabledate at : atdmap.values()) {
            if (at.getType() == 普通夺宝) {
                at1 = at;
            }
            if (at.getType() == 高级夺宝) {
                at2 = at;
            }
        }

        DateTime nowdt = DateTime.now();
        long ntime = nowdt.getMillis();

        long refreshfree1 = at1.getRefreshfree() * 1000;
        long utime1 = getTurntable1().getFrupdatetime().getMillis();
        if (ntime - utime1 >= refreshfree1) {
            getTurntable1().setFreerefresh(true);
            getTurntable1().setFrupdatetime(nowdt);
            set(isNewPlayer);
        }

        long refreshfree2 = at2.getRefreshfree() * 1000;
        long utime2 = getTurntable2().getFrupdatetime().getMillis();
        if (ntime - utime2 >= refreshfree2) {
            getTurntable2().setFreerefresh(true);
            getTurntable2().setFrupdatetime(nowdt);
            set(isNewPlayer);
        }
    }

    public void docheck() {
        check(false);
    }

    private void check(Boolean isNewPlayer) {

        if (running()) {
            new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.开启);
        } else {
            new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.关闭);
            return;
        }

        long luckey1 = new Currency().number(getPlayerCode(), CurrencyType.CT_普通夺宝积分, -1, isNewPlayer);
        long luckey2 = new Currency().number(getPlayerCode(), CurrencyType.CT_高级夺宝积分, -1, isNewPlayer);

        Map<String, actturntablereward> ttrmap = ActDataCenter.getAllData(actturntablereward.class, getPlayerCode());
        for (actturntablereward ttr : ttrmap.values()) {
            if (ttr.getType() == 普通夺宝) {
                //抽奖
                long num = Currency.number(getPlayerCode(), CurrencyType.CT_物品, 1033, isNewPlayer);
                if (num > 0) {
                    new TipHandle().updateTip(getPlayerCode(), TipType.活动_夺宝宝箱奖励, true);
                    return;
                }

                //宝箱
                if (luckey1 >= ttr.getCondition() && !getTurntable1().getLuckyboxs().contains(ttr.getId())) {
                    new TipHandle().updateTip(getPlayerCode(), TipType.活动_夺宝宝箱奖励, true);
                    return;
                }
            }

            if (ttr.getType() == 高级夺宝) {
                //抽奖
                long num = Currency.number(getPlayerCode(), CurrencyType.CT_物品, 1034, isNewPlayer);
                if (num > 0) {
                    new TipHandle().updateTip(getPlayerCode(), TipType.活动_夺宝宝箱奖励, true);
                    return;
                }

                //宝箱
                if (luckey2 >= ttr.getCondition() && !getTurntable2().getLuckyboxs().contains(ttr.getId())) {
                    new TipHandle().updateTip(getPlayerCode(), TipType.活动_夺宝宝箱奖励, true);
                    return;
                }
            }
        }

        new TipHandle().updateTip(getPlayerCode(), TipType.活动_夺宝宝箱奖励, false);

    }

    //redis ---------------------------------------------

    static private String key(String pcode) {
        return String.format("PLAYER:%s:ACTIVE:%S", pcode, acttype);
    }


    //是否新用户，如果是新用户则在更新红点的时候不需要再去查数据库
    public void set(Boolean isNewPlayer) {
        try {
            String key1 = key(getPlayerCode());
            setv(key1, this);
            check(isNewPlayer);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    static public ActiveModule_夺宝 get(String playerCode, Boolean isNewPlayer) {
        try {
            ActiveModule_夺宝 module = getv(key(playerCode));
            if (module == null) {

                //新用户不需要去查数据库
                if (!isNewPlayer) {
                    module = MySQLCacheDAO.getV(key(playerCode), ActiveModule_夺宝.class);
                    if (module != null) {
                        module.set(false);
                    }//同步到redis
                }

                if (module == null) {
                    module = create(playerCode);
                }
                if (module == null) {
                    return null;
                }
            }

            module.update(isNewPlayer);
            module.check(isNewPlayer);

            return module;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //存储到数据库的方法
    public static void saveToDB(String playerCode) {
        try {
            String key = key(playerCode);
            if (touchBucket(key).isExists()) {
                ActiveModule_夺宝 activeModule_夺宝 = getv(key(playerCode));
                MySQLCacheDAO.setV(key, activeModule_夺宝);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //从redis移走数据的操作
    public static void removeAllFromRedis(String playerCode) {
        try {
            touchBucket(key(playerCode)).delete();
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String lockKey() {
        return String.format("lock:%s", key(getPlayerCode()));
    }

}
